package com.zeng.plugin.util;

import com.zeng.plugin.entity.MenuView;
import org.apache.commons.lang3.StringUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class MenuViewHandle {

    private Map<String, MenuView> menuViewMap;

    public MenuViewHandle(Map<String, MenuView> menuViewMap) {
        this.menuViewMap = menuViewMap;
    }

    public void handleController(Map<String, List<String>> packageExtend, Map<String, List<String>> methodExtend, Map<String, List<String>> propertyExtend) {
        for (String s : menuViewMap.keySet()) {
            MenuView menuView = menuViewMap.get(s);
            String cs = withFile(menuView);
            if (StringUtils.isNotEmpty(cs)) {
                String tableName = menuView.getTableName();
                List<String> packages = packageExtend.get(tableName);
                List<String> methods = methodExtend.get(tableName);
                List<String> properties = propertyExtend.get(tableName);
                if (packages == null) {
                    packages = new ArrayList<>();
                    packageExtend.put(tableName, packages);
                }
                if (methods == null) {
                    methods = new ArrayList<>();
                    methodExtend.put(tableName, methods);
                }
                if (properties == null) {
                    properties = new ArrayList<>();
                    propertyExtend.put(tableName, properties);
                }

                String tableClassName = HumpStringUtil.humpStringHandle(tableName, "_");
                Map<String, Object> data = new HashMap<>();
                data.put("tableClassName", tableClassName);
                data.put("fileCode", cs);
                String parse = new FreeMarkUtil(controllerWithFileMethod, null).parse(data);
                methods.add(parse);
                packages.add("com.zeng.sys.authmd.apimodule.vo.UserVo");
                packages.add("com.zeng.sys.authmd.restfulmodule.util.TokenUtil");
                packages.add("com.zeng.sys.filemd.servicemodule.transfer.FileHttpTransfer");
                packages.add("com.zeng.sys.filemd.servicemodule.util.MultipartFileUtil");
                packages.add("com.zeng.sys.filemd.servicemodule.vo.FileRecordVo");
                packages.add("org.springframework.web.multipart.MultipartRequest");
                packages.add("javax.servlet.http.HttpServletRequest");
                properties.add("\n" +
                        "    @Autowired\n" +
                        "    MultipartFileUtil multipartFileUtil;");

            }
        }
    }

    public void handleService(Map<String, List<String>> packageExtend, Map<String, List<String>> methodExtend) {
        for (String s : menuViewMap.keySet()) {
            MenuView menuView = menuViewMap.get(s);
            String cs = withFile(menuView);
            if (StringUtils.isNotEmpty(cs)) {
                String tableName = menuView.getTableName();
                List<String> packages = packageExtend.get(tableName);
                List<String> methods = methodExtend.get(tableName);
                if (packages == null) {
                    packages = new ArrayList<>();
                    packageExtend.put(tableName, packages);
                }
                if (methods == null) {
                    methods = new ArrayList<>();
                    methodExtend.put(tableName, methods);
                }

                String tableClassName = HumpStringUtil.humpStringHandle(tableName, "_");
                Map<String, Object> data = new HashMap<>();
                data.put("tableClassName", tableClassName);
                String parse = new FreeMarkUtil(serviceWithFileMethod, null).parse(data);
                methods.add(parse);

            }
        }
    }

    public void handleServiceImpl(Map<String, List<String>> packageExtend, Map<String, List<String>> methodExtend, Map<String, List<String>> propertyExtend) {
        for (String s : menuViewMap.keySet()) {
            MenuView menuView = menuViewMap.get(s);
            String cs = withFile(menuView);
            if (StringUtils.isNotEmpty(cs)) {
                String tableName = menuView.getTableName();
                List<String> packages = packageExtend.get(tableName);
                List<String> methods = methodExtend.get(tableName);
                List<String> properties = propertyExtend.get(tableName);
                if (packages == null) {
                    packages = new ArrayList<>();
                    packageExtend.put(tableName, packages);
                }
                if (methods == null) {
                    methods = new ArrayList<>();
                    methodExtend.put(tableName, methods);
                }
                if (properties == null) {
                    properties = new ArrayList<>();
                    propertyExtend.put(tableName, properties);
                }

                String tableClassName = HumpStringUtil.humpStringHandle(tableName, "_");
                Map<String, Object> data = new HashMap<>();
                data.put("tableClassName", tableClassName);
                data.put("fileCode", cs);
                String parse = new FreeMarkUtil(serviceImplWithFileMethod, null).parse(data);
                methods.add(parse);
                packages.add("com.zeng.sys.filemd.servicemodule.service.FileRecordService");
                properties.add("    @Autowired\n" +
                        "    FileRecordService fileRecordService;");

            }
        }
    }

    public void handleWrapper(Map<String, List<String>> wrapperExtend) {
        for (String s : menuViewMap.keySet()) {
            MenuView menuView = menuViewMap.get(s);
            List<String> likeProperty = menuView.getLikeProperty();
            if (likeProperty != null && likeProperty.size() > 0) {

                String tableName = menuView.getTableName();
                String tableClassName = HumpStringUtil.humpStringHandle(tableName, "_");
                List<String> likes = wrapperExtend.get(tableName);
                if (likes == null) {
                    likes = new ArrayList<>();
                    wrapperExtend.put(tableName, likes);
                }

                String template = "<#list likeProperty as item>\n" +
                        "like(wrapper, ${tableClassName}.Fields.${item}, ${tableClassName?uncap_first}Vo.get${item?cap_first}());\n" +
                        "</#list>";

                FreeMarkUtil freeMarkUtil = new FreeMarkUtil(template, null);
                Map<String, Object> data = new HashMap<>();
                data.put("tableClassName", tableClassName);
                data.put("likeProperty", likeProperty);
                likes.add(freeMarkUtil.parse(data));

            }
        }
    }

    private String withFile(MenuView menuView){
        Map<String, Object> edit = menuView.getEdit();
        List<String> properties = (List<String>) edit.get("properties");
        Map<String, Object> propertyFromMap = (Map<String, Object>) edit.get("propertyFromMap");
        for (String property : properties) {
            Map<String, Object> temp = new HashMap<>();
            Object value = propertyFromMap.get(property);
            temp.put("type", value);
            if (((String)value).contains("upload")) {
                return property;
            }
        }
        return "";
    }

    private static String controllerWithFileMethod = "\n" +
            "    @RequestMapping(\"/addWithFile\")\n" +
            "    public Object addWithFile(${tableClassName}Vo ${tableClassName?uncap_first}Vo, MultipartRequest multipartRequest, HttpServletRequest request) {\n" +
            "        UserVo userByToken = TokenUtil.getUserByToken(request);\n" +
            "        if (userByToken == null) {\n" +
            "            return ResponseUtil.noAuthority(\"请登录\");\n" +
            "        }\n" +
            "\n" +
            "        FileRecordVo fileRecordVo = multipartFileUtil.handleFileRecordVo(multipartRequest, userByToken, \"统一附件\");\n" +
            "        if (fileRecordVo == null) {\n" +
            "            ${tableClassName?uncap_first}Service.addOne(${tableClassName?uncap_first}Vo);\n" +
            "            return ResponseUtil.success(\"只插入了记录,没有插入文件\");\n" +
            "        }\n" +
            "        FileHttpTransfer fileHttpTransfer = new FileHttpTransfer(fileRecordVo.getFileServerVo());\n" +
            "        ResponseUtil upload = fileHttpTransfer.upload(fileRecordVo);\n" +
            "        if (upload != null && upload.getStatus() == 200) {\n" +
            "            ${tableClassName?uncap_first}Vo.set${fileCode?cap_first}(fileRecordVo.getCode());\n" +
            "            return ResponseUtil.success(\"操作成功\").addData(\"${tableClassName?uncap_first}\", ${tableClassName?uncap_first}Service.addOne(${tableClassName?uncap_first}Vo));\n" +
            "\n" +
            "        } else {\n" +
            "            return ResponseUtil.serviceError(\"上传失败\");\n" +
            "        }\n" +
            "    }\n" +
            "\n" +
            "    @RequestMapping(\"/updateWithFile\")\n" +
            "    public Object updateWithFile(${tableClassName}Vo ${tableClassName?uncap_first}Vo, MultipartRequest multipartRequest, HttpServletRequest request) {\n" +
            "        UserVo userByToken = TokenUtil.getUserByToken(request);\n" +
            "        if (userByToken == null) {\n" +
            "            return ResponseUtil.noAuthority(\"请登录\");\n" +
            "        }\n" +
            "\n" +
            "        FileRecordVo fileRecordVo = multipartFileUtil.handleFileRecordVo(multipartRequest, userByToken, \"统一附件\");\n" +
            "        if (fileRecordVo == null) {\n" +
            "            ${tableClassName?uncap_first}Service.update(${tableClassName?uncap_first}Vo);\n" +
            "            return ResponseUtil.success(\"只修改了记录,没有插入文件\");\n" +
            "        }\n" +
            "        FileHttpTransfer fileHttpTransfer = new FileHttpTransfer(fileRecordVo.getFileServerVo());\n" +
            "        ResponseUtil upload = fileHttpTransfer.upload(fileRecordVo);\n" +
            "        if (upload != null && upload.getStatus() == 200) {\n" +
            "            ${tableClassName?uncap_first}Vo.set${fileCode?cap_first}(fileRecordVo.getCode());\n" +
            "            return ResponseUtil.success(\"操作成功\").addData(\"${tableClassName?uncap_first}\", ${tableClassName?uncap_first}Service.updateAndDeleteFile(${tableClassName?uncap_first}Vo));\n" +
            "        } else {\n" +
            "            return ResponseUtil.serviceError(\"上传失败\");\n" +
            "        }\n" +
            "    }\n" +
            "\n" +
            "    @RequestMapping(\"/deleteWithFile\")\n" +
            "    public Object deleteWithFile(String code) {\n" +
            "        Integer delete = this.${tableClassName?uncap_first}Service.deleteFileAnd${tableClassName}(code);\n" +
            "        return ResponseUtil.success(\"操作成功\").addData(\"deleteCount\", delete);\n" +
            "    }\n" +
            "    @RequestMapping(\"/batchDeleteWithFile\")\n" +
            "    public Object batchDeleteWithFile(@RequestBody List<String> codes) {\n" +
            "        Integer integer = this.${tableClassName?uncap_first}Service.batchDeleteFileAnd${tableClassName}(codes);\n" +
            "\n" +
            "        return ResponseUtil.success(\"操作成功\").addData(\"deleteCount\", integer);\n" +
            "    }";

    private static String serviceWithFileMethod = "    Integer updateAndDeleteFile(${tableClassName}Vo ${tableClassName?uncap_first}Vo);\n" +
            "\n" +
            "    Object deleteFile(String ${tableClassName?uncap_first}Code);\n" +
            "\n" +
            "    Object batchDeleteFile(List<String> ${tableClassName?uncap_first}Codes);\n" +
            "\n" +
            "    Integer deleteFileAnd${tableClassName}(String ${tableClassName?uncap_first}Code);\n" +
            "\n" +
            "    Integer batchDeleteFileAnd${tableClassName}(List<String> ${tableClassName?uncap_first}Codes);";

    private static String serviceImplWithFileMethod = "    @Override\n" +
            "    public Integer updateAndDeleteFile(${tableClassName}Vo ${tableClassName?uncap_first}Vo) {\n" +
            "        deleteFile(${tableClassName?uncap_first}Vo.getCode());\n" +
            "        return update(${tableClassName?uncap_first}Vo);\n" +
            "    }\n" +
            "\n" +
            "    @Override\n" +
            "    public Object deleteFile(String ${tableClassName?uncap_first}Code) {\n" +
            "        if (${tableClassName?uncap_first}Code == null) {\n" +
            "            return null;\n" +
            "        }\n" +
            "        ${tableClassName}Vo oneByCode = getOneByCode(${tableClassName?uncap_first}Code);\n" +
            "        return fileRecordService.deleteRecordAndFile(oneByCode.get${fileCode?cap_first}());\n" +
            "    }\n" +
            "\n" +
            "    @Override\n" +
            "    public Object batchDeleteFile(List<String> ${tableClassName?uncap_first}Codes) {\n" +
            "        if (CollectionUtils.isEmpty(${tableClassName?uncap_first}Codes)) {\n" +
            "            return null;\n" +
            "        }\n" +
            "        List<${tableClassName}> ${tableClassName?uncap_first}s = ${tableClassName?uncap_first}Mapper.selectBatchIds(${tableClassName?uncap_first}Codes);\n" +
            "        List<${tableClassName}Vo> ${tableClassName?uncap_first}Vos = ${tableClassName}Vo.list${tableClassName}Vo(${tableClassName?uncap_first}s);\n" +
            "        return fileRecordService.deleteRecordsAndFiles(${tableClassName?uncap_first}Vos.stream().map(${tableClassName}Vo::get${fileCode?cap_first}).collect(Collectors.toList()));\n" +
            "    }\n" +
            "\n" +
            "    @Override\n" +
            "    public Integer deleteFileAnd${tableClassName}(String ${tableClassName?uncap_first}Code) {\n" +
            "        deleteFile(${tableClassName?uncap_first}Code);\n" +
            "        return delete(${tableClassName?uncap_first}Code);\n" +
            "    }\n" +
            "\n" +
            "    @Override\n" +
            "    public Integer batchDeleteFileAnd${tableClassName}(List<String> ${tableClassName?uncap_first}Codes) {\n" +
            "        batchDeleteFile(${tableClassName?uncap_first}Codes);\n" +
            "        return batchDelete(${tableClassName?uncap_first}Codes);\n" +
            "    }";
}
